﻿
// VideoStudioAssistDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "VideoStudioAssist.h"
#include "VideoStudioAssistDlg.h"
#include "afxdialogex.h"
#include "PresenterImpl.h"
#include "Log.h"
#include "Utils.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


void ThreadLoadExcel(LPVOID pParam){
	CVideoStudioAssistDlg* dlg = (CVideoStudioAssistDlg*)pParam;
	dlg->presenter->loadData();
}

void ThreadSaveExcel(LPVOID pParam){
	CVideoStudioAssistDlg* dlg = (CVideoStudioAssistDlg*)pParam;
	dlg->presenter->saveToExcel();
}

void ThreadReleaseExcel(LPVOID pParam){
	ExcelHelper::GetInstance()->closeExcel();
	ExcelHelper::GetInstance()->release();
}

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CVideoStudioAssistDlg 对话框




CVideoStudioAssistDlg::CVideoStudioAssistDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CVideoStudioAssistDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CVideoStudioAssistDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_SUBTITLE, mListCtrlSubtitle);
	DDX_Control(pDX, IDC_EDIT_ID, mEditId);
	DDX_Control(pDX, IDC_EDIT_START_HOUR, mEditStartHour);
	DDX_Control(pDX, IDC_EDIT_START_MIN, mEditStartMin);
	DDX_Control(pDX, IDC_EDIT_START_SEC, mEditStartSec);
	DDX_Control(pDX, IDC_EDIT_START_FRAME, mEditStartFrame);

	DDX_Control(pDX, IDC_EDIT_END_HOUR, mEditEndHour);
	DDX_Control(pDX, IDC_EDIT_END_MIN, mEditEndMin);
	DDX_Control(pDX, IDC_EDIT_END_SEC, mEditEndSec);
	DDX_Control(pDX, IDC_EDIT_END_FRAME, mEditEndFrame);


	DDX_Control(pDX, IDC_EDIT_FRAME_RATE, mEditFrameRate);


	DDX_Control(pDX, IDC_EDIT_SUBTITLE, mEditSubtitle);
	DDX_Control(pDX, IDC_EDIT_SUBTITLE_PATH, mEditSubtitlePath);
	DDX_Control(pDX, IDC_SPIN_START_HOUR, mSpinStartHour);
	DDX_Control(pDX, IDC_SPIN_START_MIN, mSpinStartMin);
	DDX_Control(pDX, IDC_SPIN_START_SEC, mSpinStartSec);
	DDX_Control(pDX, IDC_SPIN_START_FRAME, mSpinStartFrame);
	DDX_Control(pDX, IDC_SPIN_END_HOUR, mSpinEndHour);
	DDX_Control(pDX, IDC_SPIN_END_MIN, mSpinEndMin);
	DDX_Control(pDX, IDC_SPIN_END_SEC, mSpinEndSec);
	DDX_Control(pDX, IDC_SPIN_END_FRAME, mSpinEndFrame);
	DDX_Control(pDX, IDC_SPIN_FRAME_RATE, mSpinFrameRate);
}

BEGIN_MESSAGE_MAP(CVideoStudioAssistDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_SAVE, &CVideoStudioAssistDlg::OnBnClickedButtonSave)
	ON_BN_CLICKED(IDC_BUTTON_DELETE, &CVideoStudioAssistDlg::OnBnClickedButtonDelete)
	ON_NOTIFY(NM_CLICK, IDC_LIST_SUBTITLE, &CVideoStudioAssistDlg::listItemClick)
	ON_WM_DESTROY()
	ON_MESSAGE(WM_UPDATE_UI,&CVideoStudioAssistDlg::OnUpdateUI)
	
	ON_BN_CLICKED(IDC_BUTTON_BROWSER_SUBTITLE, &CVideoStudioAssistDlg::OnBnClickedButtonBrowserSubtitle)
	ON_COMMAND(ID_MENUITEM_EXIT, &CVideoStudioAssistDlg::OnMenuitemExit)
	ON_COMMAND(ID_MENUITEM_OPEN, &CVideoStudioAssistDlg::OnMenuitemOpen)
	ON_COMMAND(ID_MENUITEM_EXPORT_VIDEOSTUDIO, &CVideoStudioAssistDlg::OnMenuitemExportVideostudio)
	ON_BN_CLICKED(IDC_BUTTON_MOVEUP, &CVideoStudioAssistDlg::OnBnClickedButtonMoveup)
	ON_BN_CLICKED(IDC_BUTTON_MOVEDOWN, &CVideoStudioAssistDlg::OnBnClickedButtonMovedown)
	ON_COMMAND(ID_MENUITEM_SAVE, &CVideoStudioAssistDlg::OnMenuitemSave)
	ON_WM_ACTIVATE()
END_MESSAGE_MAP()

void initSpinEdits(CEdit *p_edits[],int size){
	for(int i=0;i<size;i++)
	{
		p_edits[i]->SetWindowTextW(L"00");
	}
}

void initEditsFocusEvent(CVideoStudioAssistDlg* dlg,CBaseEdit *p_edits[],int size){
	for(int i=0;i<size;i++)
	{
		p_edits[i]->setOnSetFocus(dlg,CVideoStudioAssistDlg::EditCallbackFunc);
	}
}

void init0to59(CNumberEdit *p_edit)
{
	p_edit->setRange(0,59);
	p_edit->SetLimitText(2);
}

void init0to99(CNumberEdit *p_edit)
{
	p_edit->setRange(0,99);
	p_edit->SetLimitText(2);
}
// CVideoStudioAssistDlg 消息处理程序

BOOL CVideoStudioAssistDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	CLog::WriteLog(L"OnInitDialog");

	DWORD dwStyle = this->mListCtrlSubtitle.GetExtendedStyle();//添加列表框的网格线！！！
	dwStyle |= LVS_EX_FULLROWSELECT;
	dwStyle |= LVS_EX_GRIDLINES;
	this->mListCtrlSubtitle.SetExtendedStyle(dwStyle);

	this->mListCtrlSubtitle.InsertColumn(0,L"编号",LVCFMT_LEFT,50);
	this->mListCtrlSubtitle.InsertColumn(1,L"开始时间",LVCFMT_LEFT,90);
	this->mListCtrlSubtitle.InsertColumn(2,L"结束时间",LVCFMT_LEFT,90);
	this->mListCtrlSubtitle.InsertColumn(3,L"字幕",LVCFMT_LEFT,900);

	this->presenter = new PresenterImpl(this);


	//初始化为00
	CEdit *p_edits[]={
		&this->mEditStartHour,
		&this->mEditStartMin,
		&this->mEditStartSec,
		&this->mEditStartFrame,
		&this->mEditEndHour,
		&this->mEditEndMin,
		&this->mEditEndSec,
		&this->mEditEndFrame,
		&this->mEditFrameRate
	};
	initSpinEdits(p_edits,sizeof(p_edits)/sizeof(CEdit*));

	init0to59(&mEditStartMin);
	init0to59(&mEditStartSec);
	init0to99(&mEditStartFrame);

	init0to59(&mEditEndMin);
	init0to59(&mEditEndSec);
	init0to99(&mEditEndFrame);


	//加入焦点事件控制
	CBaseEdit *p_edits_event[]={
		&this->mEditId,
		&this->mEditStartHour,
		&this->mEditStartMin,
		&this->mEditStartSec,
		&this->mEditStartFrame,
		&this->mEditEndHour,
		&this->mEditEndMin,
		&this->mEditEndSec,
		&this->mEditEndFrame,
		&this->mEditFrameRate,
		&this->mEditSubtitle,
		&this->mEditSubtitlePath	
	};
	initEditsFocusEvent(this,p_edits_event,sizeof(p_edits_event)/sizeof(CBaseEdit*));

	//绑定spin到edit
	this->mSpinStartHour.SetBuddy(&this->mEditStartHour);
	this->mSpinStartMin.SetBuddy(&this->mEditStartMin);
	this->mSpinStartSec.SetBuddy(&this->mEditStartSec);
	this->mSpinStartFrame.SetBuddy(&this->mEditStartFrame);

	this->mSpinEndHour.SetBuddy(&this->mEditEndHour);
	this->mSpinEndMin.SetBuddy(&this->mEditEndMin);
	this->mSpinEndSec.SetBuddy(&this->mEditEndSec);
	this->mSpinEndFrame.SetBuddy(&this->mEditEndFrame);

	this->mSpinFrameRate.SetBuddy(&this->mEditFrameRate);

	this->mListCtrlSubtitle.setCallback(this,CVideoStudioAssistDlg::ListCtrlExtCallbackFunc);
	//SetTimer(WP_SHOW_LOADING,100,NULL);
	this->strFilePath = L"";
	this->mEditGetFocus = NULL;
	return FALSE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CVideoStudioAssistDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CVideoStudioAssistDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CVideoStudioAssistDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

CString CVideoStudioAssistDlg::getExportPath() const
{
	CString exportPath;
	this->mEditSubtitlePath.GetWindowTextW(exportPath);
	return exportPath;
}

//=====================IView======================
void CVideoStudioAssistDlg::setListData(vector<Entity> list)
{
	this->mListCtrlSubtitle.DeleteAllItems();

	long frameRate = this->getFrameRate();
	for(unsigned int i = 0;i < list.size();i++)
	{
		Entity entity = list[i];
		this->mListCtrlSubtitle.InsertItem(i,entity.id);
		this->mListCtrlSubtitle.SetItemText(i,1,entity.getStartTimeString());
		this->mListCtrlSubtitle.SetItemText(i,2,entity.getEndTimeString());
		this->mListCtrlSubtitle.SetItemText(i,3,entity.subtitle);
	}
}

Entity CVideoStudioAssistDlg::getCurrentRecord()
{
	CString tmp;

	Entity entity;

	this->mEditId.GetWindowTextW(tmp);
	entity.id = tmp;

	//startTime
	entity.startHour = this->mEditStartHour.getValue();

	entity.startMin = this->mEditStartMin.getValue();

	entity.startSec = this->mEditStartSec.getValue();

	entity.startFrame = this->mEditStartFrame.getValue();

	//endTime
	entity.endHour = this->mEditEndHour.getValue();

	entity.endMin = this->mEditEndMin.getValue();

	entity.endSec = this->mEditEndSec.getValue();

	entity.endFrame = this->mEditEndFrame.getValue();

	//Subtitle
	this->mEditSubtitle.GetWindowTextW(tmp);
	entity.subtitle = tmp;

	return entity;
}

void CVideoStudioAssistDlg::setSelectedData(Entity entity)
{
	long frameRate = this->mEditFrameRate.getValue();

	this->mEditId.SetWindowTextW(entity.id);

	//start time
	this->mEditStartHour.setValue(entity.getStartHour());

	this->mEditStartMin.setValue(entity.getStartMin());

	this->mEditStartSec.setValue(entity.getStartSec());

	this->mEditStartFrame.setValue(entity.getStartFrame());

	//end time
	this->mEditEndHour.setValue(entity.getEndHour());

	this->mEditEndMin.setValue(entity.getEndMin());

	this->mEditEndSec.setValue(entity.getEndSec());

	this->mEditEndFrame.setValue(entity.getEndFrame());

	//subtitle
	this->mEditSubtitle.SetWindowTextW(entity.subtitle);

}

void CVideoStudioAssistDlg::showMessageBox(CString message)
{
	MessageBox(message,L"提示");
}

HWND CVideoStudioAssistDlg::getHwnd()
{
	return this->m_hWnd;
}

CString CVideoStudioAssistDlg::getOpenFilePath() const
{
	return this->strFilePath;
}

long CVideoStudioAssistDlg::getFrameRate()
{
	return this->mEditFrameRate.getValue();
}
void CVideoStudioAssistDlg::setFrameRate(long frameRate)
{
	CString tmp;
	tmp.Format(L"%ld",frameRate);
	this->mEditFrameRate.SetWindowTextW(tmp);
}

void CVideoStudioAssistDlg::setTitle(CString title)
{
	this->SetWindowTextW(title);
}
//==================================================

void CVideoStudioAssistDlg::OnBnClickedButtonSave()
{
	// TODO: 在此添加控件通知处理程序代码
	this->presenter->saveRecord();
}


void CVideoStudioAssistDlg::OnBnClickedButtonDelete()
{
	// TODO: 在此添加控件通知处理程序代码
	this->presenter->deleteRecord();
}


BOOL CVideoStudioAssistDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if(pMsg->message == WM_KEYDOWN)
	{
		if(pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN)
		{
			return TRUE;
		}
	}
	return __super::PreTranslateMessage(pMsg);
}

void CVideoStudioAssistDlg::listItemClick(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	int mark = this->mListCtrlSubtitle.GetSelectionMark();

	this->presenter->selectListItem(mark);
	//this->mEditId.SetWindowTextW(this->mListCtrlSubtitle.GetItemText(mark,0));
}



void CVideoStudioAssistDlg::OnDestroy()
{
	delete this->presenter;
	CLog::WriteLog(L"OnDestroy");
	__super::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
}

afx_msg LRESULT  CVideoStudioAssistDlg::OnUpdateUI(WPARAM wParam, LPARAM lParam)
{
	switch(wParam)
	{
		case WP_SHOW_LOADING:
		{
			CLog::WriteLog(L"WP_SHOW_LOADING");
			mLoadingDlg.DoModal();
		}
		break;
		case WP_HIDE_LOADING:
		{
			CLog::WriteLog(L"WP_HIDE_LOADING");
			mLoadingDlg.EndDialog(0);
		}
		break;
		case WP_LOAD_EXCEL:
		{
			mLoadingDlg.EndDialog(0);
		}
		break;
		case WP_SAVE_EXCEL:
		{
			mLoadingDlg.EndDialog(0);
		}
		break;
		case WP_RELEASE_EXCEL:
		{
			mLoadingDlg.EndDialog(0);
			EndDialog(0);
		}
		break;
	}
	return 0;
}


void process(CEdit &edit,int updownDelta)
{
	CString tmp;
	edit.GetWindowTextW(tmp);
	if(tmp.IsEmpty()){
		return;
	}
	long original = _ttol(tmp);
	if(1 == updownDelta) //此值为1，说明点击了Spin往下
	{
		if(original>0)
		{
			original -= 1;
		}
	}
	else if(-1 == updownDelta) //此值为-1，说明点击了Spin往上
	{
		original += 1;
	}
	tmp.Format(L"%02ld",original);
	edit.SetWindowTextW(tmp);
}

void CVideoStudioAssistDlg::OnBnClickedButtonBrowserSubtitle()
{
	// 设置过滤器   
	TCHAR szFilter[] = _T("字幕文件(*.srt)|*.srt|所有文件(*.*)|*.*||");
	// 构造打开文件对话框   
	CFileDialog fileDlg(FALSE, _T("srt"), NULL, 0, szFilter, this);
	CString strFilePath;
 
	// 显示打开文件对话框   
	if (IDOK == fileDlg.DoModal())
	{
		// 如果点击了文件对话框上的“打开”按钮，则将选择的文件路径显示到编辑框里   
		strFilePath = fileDlg.GetPathName();
		this->mEditSubtitlePath.SetWindowTextW(strFilePath);
	}
}


void CVideoStudioAssistDlg::OnMenuitemExit()
{
	// TODO: 在此添加命令处理程序代码
	CVideoStudioAssistApp* app = (CVideoStudioAssistApp*)AfxGetApp();
	CThreadQueueMessage message;
	message.m_hWnd = this->m_hWnd;
	message.wParam = WP_RELEASE_EXCEL;
	message.pParam = this;
	message.callback = &ThreadReleaseExcel;
	app->mQueueMessage.push(message);
	mLoadingDlg.setTips(L"正在释放资源...");
	mLoadingDlg.DoModal();
	
}


void CVideoStudioAssistDlg::OnMenuitemOpen()
{
	// TODO: 在此添加命令处理程序代码
	// 设置过滤器   
	TCHAR szFilter[] = _T("Excel 缓存文件(*.xlsx)|*.xlsx|所有文件(*.*)|*.*||");
	// 构造打开文件对话框   
	CFileDialog fileDlg(TRUE, _T("xlsx"), NULL, 0, szFilter, this);
 
	// 显示打开文件对话框   
	if (IDOK == fileDlg.DoModal())
	{
		// 如果点击了文件对话框上的“打开”按钮，则将选择的文件路径显示到编辑框里
		this->strFilePath = fileDlg.GetPathName();
		CVideoStudioAssistApp* app = (CVideoStudioAssistApp*)AfxGetApp();
		CThreadQueueMessage message;
		message.m_hWnd = this->m_hWnd;
		message.wParam = WP_LOAD_EXCEL;
		message.pParam = this;
		message.callback = &ThreadLoadExcel;
		app->mQueueMessage.push(message);
		mLoadingDlg.setTips(L"正在加载字幕excel文件...");
		mLoadingDlg.DoModal();
	}
}

void CVideoStudioAssistDlg::OnMenuitemSave()
{
	// TODO: 在此添加命令处理程序代码
	if (strFilePath == L"")
	{
		this->showMessageBox(L"请先打开文件");
		return;
	}
	CVideoStudioAssistApp* app = (CVideoStudioAssistApp*)AfxGetApp();
	CThreadQueueMessage message;
	message.m_hWnd = this->m_hWnd;
	message.wParam = WP_SAVE_EXCEL;
	message.pParam = this;
	message.callback = &ThreadSaveExcel;
	app->mQueueMessage.push(message);
	mLoadingDlg.setTips(L"正在缓存excel文件...");
	mLoadingDlg.DoModal();
	
}

void CVideoStudioAssistDlg::OnMenuitemExportVideostudio()
{
	// TODO: 在此添加命令处理程序代码
	this->presenter->exportSubtitle();
}


void CVideoStudioAssistDlg::OnBnClickedButtonMoveup()
{
	// TODO: 在此添加控件通知处理程序代码
	this->presenter->moveUp();
}


void CVideoStudioAssistDlg::OnBnClickedButtonMovedown()
{
	// TODO: 在此添加控件通知处理程序代码
	this->presenter->moveDown();
}





void CVideoStudioAssistDlg::EditCallbackFunc(CDialogEx* dlg,CEdit* edit)
{
	CVideoStudioAssistDlg* cdlg = (CVideoStudioAssistDlg*)dlg;
	cdlg->mEditGetFocus = (CBaseEdit*)edit;
}

void CVideoStudioAssistDlg::ListCtrlExtCallbackFunc(CDialogEx* dlg,int index)
{
	CVideoStudioAssistDlg* cdlg = (CVideoStudioAssistDlg*)dlg;
	cdlg->presenter->deleteRecord(index);
}

void CVideoStudioAssistDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
	__super::OnActivate(nState, pWndOther, bMinimized);

	// TODO: 在此处添加消息处理程序代码
	if (NULL != this->mEditGetFocus)
	{
		this->mEditGetFocus->SetFocus();
	}
}
